package com.cjg.single;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class demo02 {
    private static boolean cjg =false;
    //私有化构造方法
    private  demo02(){
        synchronized (demo02.class){
            if (cjg==false){
                cjg=true;
            }else {
                throw new RuntimeException("少搞事");
            }

        }
        System.out.println(Thread.currentThread().getName());
    }
    //类不进行初始化
    private  volatile static demo02 d;
    //一个公共方法
    public static demo02 getInstance(){
        //加锁 双重检测锁 因为这个还可以被main和gc线程获取所有判定的两次
        //不是原子性操作
        /**
         * 1.分配内存空间
         * 2.执行构造方法,初始化对象
         * 3.吧对象执行空间
         * 4. 可能执行 A:132
         * B  进去 没有完成构造 为null 指令重排  需要加上volatile
         */
        if (d==null){
            synchronized (demo02.class){
                if (d==null){
                    d=new demo02();
                }
            }
        }

        return d;
    }

//    public static void main(String[] args) {
//        //多线程下单线程出问题 需要加锁
//        for (int i = 0; i <10 ; i++) {
//            new Thread(()->{
//               d.getInstance();
//            }).start();
//        }
//    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//        demo02 instance = demo02.getInstance();

        Field cjg = demo02.class.getDeclaredField("cjg");
        //反射破坏了单例
        Constructor<demo02> declaredConstructor = demo02.class.getDeclaredConstructor();
        Constructor<demo02> declaredConstructor1 = demo02.class.getDeclaredConstructor();
       //关闭检查
        cjg.setAccessible(true);
        declaredConstructor.setAccessible(true);
        demo02 demo02 = declaredConstructor.newInstance();
        cjg.set(demo02,false);
        com.cjg.single.demo02 demo021 = declaredConstructor1.newInstance();
        System.out.println(demo021);
        System.out.println(demo02);

    }
    

}
